"""
实现角色
创建者：Carburn Ashroom
2024.1.16
"""

from enum import IntEnum
from math import sqrt

import config
from PySide6.QtCore import Qt, QPointF, QRectF, QSizeF
from PySide6.QtGui import QImage, QPainter


class Char:
    """Char类是一个可以移动的角色"""
    def __init__(self, img, width, point, speed, direct, screen):
        self.limg = QImage(img)
        self.rimg = self.limg.mirrored(True, False)
        self.right = direct
        self.scrn = screen
        self.width = width
        self.height = width * self.limg.height() / self.limg.width()
        self.pos = point
        self.speed = speed

        if direct:
            self.rimg, self.limg = self.limg, self.rimg

    def draw(self, dest):
        """绘制"""
        pa = QPainter(dest)
        img = self.rimg if self.right else self.limg
        pa.drawImage(self.rect(), img)

    def rect(self):
        """获取角色对应矩形区域"""
        return QRectF(self.pos, QSizeF(self.width, self.height))

    def move_to(self, pos):
        """移动到目标位置"""
        if pos.x() > self.pos.x():
            self.right = True
        elif pos.x() < self.pos.x():
            self.right = False
        self.pos = pos
        self.ctrl_overflow()

    def ctrl_overflow(self):
        """防止溢出屏幕"""
        if self.pos.x() < 0:
            self.pos.setX(0)
        elif self.pos.x() + self.width > self.scrn.width:
            self.pos.setX(self.scrn.width-self.width)
        if self.pos.y() < 0:
            self.pos.setY(0)
        elif self.pos.y() + self.height > self.scrn.height:
            self.pos.setY(self.scrn.height-self.height)

    def get_center(self):
        """返回当前角色矩形中心点"""
        return self.rect().center()

    def move_center_c(self, obj_char):
        """中心向指定角色的中心靠拢"""
        self.move_center_p(obj_char.get_center())

    def move_center_p(self, point):
        """中心向指定点靠拢"""
        ct = self.get_center()
        dx = point.x() - ct.x()
        dy = point.y() - ct.y()
        direct = sqrt(dx**2+dy**2)
        if direct < self.speed:
            return
        dx *= self.speed / direct
        dy *= self.speed / direct
        pos = QPointF(self.pos.x()+dx, self.pos.y()+dy)
        self.move_to(pos)

    def intersects(self, char):
        """判断两个角色是否碰撞"""
        return self.rect().intersects(char.rect())


class Direct(IntEnum):
    """方向"""
    UP = 0
    RIGHT = 1
    DOWN = 2
    LEFT = 3


class Sheep(Char):
    """Sheep类是一个喜羊羊"""
    def __init__(self, key, screen, img=config.SHEEP_DIR, width=config.SHEEP_WIDTH, point=QPointF(),
                 speed=config.SHEEP_SPEED, direct=config.SHEEP_RIGHT):
        super().__init__(img, width, point, speed, direct, screen)
        self.keys = [False, False, False, False]
        self.mouse = QPointF()
        self.key_ctrl = key

    def update(self):
        """更新每一帧"""
        if self.key_ctrl:
            dx, dy = 0, 0
            if self.keys[Direct.UP]:
                dy -= self.speed
            if self.keys[Direct.DOWN]:
                dy += self.speed
            if self.keys[Direct.LEFT]:
                dx -= self.speed
            if self.keys[Direct.RIGHT]:
                dx += self.speed
            new_pos = QPointF(self.pos.x()+dx, self.pos.y()+dy)
            self.move_to(new_pos)
        else:
            self.move_center_p(self.mouse)

    def key_press(self, event):
        """按下键盘"""
        if event.isAutoRepeat():
            return
        match event.key():
            case Qt.Key.Key_A:
                self.keys[Direct.LEFT] = True
            case Qt.Key.Key_S:
                self.keys[Direct.DOWN] = True
            case Qt.Key.Key_W:
                self.keys[Direct.UP] = True
            case Qt.Key.Key_D:
                self.keys[Direct.RIGHT] = True

    def key_release(self, event):
        """松开按键"""
        if event.isAutoRepeat():
            return
        match event.key():
            case Qt.Key.Key_A:
                self.keys[Direct.LEFT] = False
            case Qt.Key.Key_S:
                self.keys[Direct.DOWN] = False
            case Qt.Key.Key_W:
                self.keys[Direct.UP] = False
            case Qt.Key.Key_D:
                self.keys[Direct.RIGHT] = False

    def mouse_move(self, event):
        """鼠标移动"""
        self.mouse = event.position()


class Wolf(Char):
    """Wolf类是一只灰太狼"""
    def __init__(self, point, screen, img=config.WOLF_DIR, width=config.WOLF_WIDTH, speed=config.WOLF_SPEED,
                 direct=config.WOLF_RIGHT):
        super().__init__(img, width, point, speed, direct, screen)

    def update(self, sheep):
        """更新每一帧"""
        self.move_center_c(sheep)
        return self.intersects(sheep)
